<template>
  <div class="modal fade" :id="modalId" tabindex="-1" :aria-labelledby="modalId + 'Label'" aria-hidden="true">
    <div class="modal-dialog" :class="modalClasses">
      <div class="modal-content">
        <!-- 模态框头部 -->
        <div class="modal-header" :class="headerClass">
          <h5 class="modal-title" :id="modalId + 'Label'">
            <i v-if="icon" :class="icon" class="me-2"></i>
            {{ title }}
          </h5>
          <button type="button" class="btn-close" :class="closeButtonClass" data-bs-dismiss="modal" aria-label="关闭"></button>
        </div>
        
        <!-- 模态框主体 -->
        <div class="modal-body" :class="bodyClass">
          <slot></slot>
        </div>
        
        <!-- 模态框底部 -->
        <div v-if="showFooter" class="modal-footer" :class="footerClass">
          <slot name="footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
              <i class="bi bi-x-lg me-1"></i>
              {{ cancelText }}
            </button>
            <button v-if="showConfirm" type="button" class="btn" :class="confirmButtonClass" @click="handleConfirm" :disabled="confirmDisabled">
              <span v-if="confirmLoading" class="spinner-border spinner-border-sm me-2"></span>
              <i v-else-if="confirmIcon" :class="confirmIcon" class="me-1"></i>
              {{ confirmText }}
            </button>
          </slot>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue'

const props = defineProps({
  modalId: {
    type: String,
    required: true
  },
  title: {
    type: String,
    default: '标题'
  },
  icon: {
    type: String,
    default: ''
  },
  size: {
    type: String,
    default: 'md', // sm, md, lg, xl
    validator: (value) => ['sm', 'md', 'lg', 'xl'].includes(value)
  },
  fullscreen: {
    type: [Boolean, String],
    default: false // true, 'sm-down', 'md-down', 'lg-down', 'xl-down', 'xxl-down'
  },
  centered: {
    type: Boolean,
    default: false
  },
  scrollable: {
    type: Boolean,
    default: false
  },
  showFooter: {
    type: Boolean,
    default: true
  },
  showConfirm: {
    type: Boolean,
    default: true
  },
  confirmText: {
    type: String,
    default: '确认'
  },
  cancelText: {
    type: String,
    default: '取消'
  },
  confirmIcon: {
    type: String,
    default: 'bi bi-check-lg'
  },
  confirmType: {
    type: String,
    default: 'primary', // primary, success, danger, warning, info
    validator: (value) => ['primary', 'success', 'danger', 'warning', 'info', 'secondary'].includes(value)
  },
  confirmDisabled: {
    type: Boolean,
    default: false
  },
  confirmLoading: {
    type: Boolean,
    default: false
  },
  headerClass: {
    type: String,
    default: ''
  },
  bodyClass: {
    type: String,
    default: ''
  },
  footerClass: {
    type: String,
    default: ''
  },
  responsive: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['confirm', 'cancel', 'show', 'hide'])

const screenWidth = ref(window.innerWidth)

const modalClasses = computed(() => {
  const classes = []
  
  // 尺寸类
  if (props.size !== 'md') {
    classes.push(`modal-${props.size}`)
  }
  
  // 全屏类
  if (props.fullscreen === true) {
    classes.push('modal-fullscreen')
  } else if (typeof props.fullscreen === 'string') {
    classes.push(`modal-fullscreen-${props.fullscreen}`)
  }
  
  // 居中类
  if (props.centered) {
    classes.push('modal-dialog-centered')
  }
  
  // 滚动类
  if (props.scrollable) {
    classes.push('modal-dialog-scrollable')
  }
  
  // 响应式类
  if (props.responsive) {
    if (screenWidth.value <= 576) {
      classes.push('modal-responsive-sm')
    } else if (screenWidth.value <= 768) {
      classes.push('modal-responsive-md')
    }
  }
  
  return classes
})

const confirmButtonClass = computed(() => {
  return `btn-${props.confirmType}`
})

const closeButtonClass = computed(() => {
  // 如果头部有深色背景，使用白色关闭按钮
  if (props.headerClass.includes('bg-primary') || 
      props.headerClass.includes('bg-dark') || 
      props.headerClass.includes('bg-success') ||
      props.headerClass.includes('bg-danger')) {
    return 'btn-close-white'
  }
  return ''
})

const handleConfirm = () => {
  emit('confirm')
}

const handleResize = () => {
  screenWidth.value = window.innerWidth
}

onMounted(() => {
  if (props.responsive) {
    window.addEventListener('resize', handleResize)
  }
  
  // 监听模态框事件
  const modalElement = document.getElementById(props.modalId)
  if (modalElement) {
    modalElement.addEventListener('show.bs.modal', () => emit('show'))
    modalElement.addEventListener('hide.bs.modal', () => emit('hide'))
  }
})

onUnmounted(() => {
  if (props.responsive) {
    window.removeEventListener('resize', handleResize)
  }
})
</script>

<style scoped>
/* 响应式模态框样式 */
.modal-responsive-sm {
  margin: 0.25rem;
  max-width: calc(100% - 0.5rem);
}

.modal-responsive-md {
  margin: 0.5rem;
  max-width: calc(100% - 1rem);
}

/* 模态框头部渐变背景 */
.modal-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-bottom: none;
  border-radius: 0.5rem 0.5rem 0 0;
}

.modal-header .btn-close {
  filter: invert(1);
}

/* 模态框主体 */
.modal-body {
  background: #f8f9fc;
  max-height: 70vh;
  overflow-y: auto;
}

/* 模态框底部 */
.modal-footer {
  background: #f8f9fc;
  border-top: 1px solid #e3e6f0;
  border-radius: 0 0 0.5rem 0.5rem;
}

/* 移动端优化 */
@media (max-width: 768px) {
  .modal-dialog {
    margin: 0.5rem;
    max-width: calc(100% - 1rem);
  }
  
  .modal-xl,
  .modal-lg {
    max-width: calc(100% - 1rem);
  }
  
  .modal-body {
    padding: 1rem;
    max-height: 60vh;
  }
  
  .modal-header {
    padding: 0.75rem 1rem;
  }
  
  .modal-footer {
    padding: 0.75rem 1rem;
    flex-direction: column;
    gap: 0.5rem;
  }
  
  .modal-footer .btn {
    width: 100%;
  }
}

@media (max-width: 576px) {
  .modal-dialog {
    margin: 0.25rem;
    max-width: calc(100% - 0.5rem);
  }
  
  .modal-body {
    padding: 0.75rem;
    max-height: 50vh;
  }
  
  .modal-header {
    padding: 0.5rem 0.75rem;
  }
  
  .modal-footer {
    padding: 0.5rem 0.75rem;
  }
  
  .modal-title {
    font-size: 1rem;
  }
}

/* 滚动条美化 */
.modal-body::-webkit-scrollbar {
  width: 6px;
}

.modal-body::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.modal-body::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.modal-body::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 动画优化 */
.modal.fade .modal-dialog {
  transition: transform 0.3s ease-out;
  transform: translate(0, -50px);
}

.modal.show .modal-dialog {
  transform: none;
}

/* 按钮加载状态 */
.btn .spinner-border-sm {
  width: 0.875rem;
  height: 0.875rem;
}

/* 深色主题支持 */
@media (prefers-color-scheme: dark) {
  .modal-content {
    background-color: #2d3748;
    color: #e2e8f0;
  }
  
  .modal-header {
    border-bottom-color: #4a5568;
  }
  
  .modal-footer {
    border-top-color: #4a5568;
    background: #2d3748;
  }
  
  .modal-body {
    background: #2d3748;
  }
}
</style>